package com.young.rabbitmq.returnlistener;

import com.rabbitmq.client.*;
import com.young.rabbitmq.util.ConnectionUtil;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

/**
 * 消息确认机制之return 模式
 *
 * return Listener用于处理一些不可路由的消息（在某些情况下，如果我们发送消息的时候，当前的exchange或者routeKey路由不到的时候，
 * 这个时候如果我们需要监听这种不可到达的消息，就要使用Return Listener）
 *
 * 在return模式下只有成功到达了交换机且未到达队列才会触发回调函数
 */
public class Producer {

    //交换机名称
    static final String TOPIC_EXCHAGE = "test_return_exchange";

    public static void main(String[] args) throws IOException, TimeoutException {
        Connection connection = ConnectionUtil.buildConnection();
        Channel channel = connection.createChannel();

        /**
         * 声明交换机
         * 参数1：交换机名称
         * 参数2：交换机类型，fanout、topic、direct、headers
         */
        channel.exchangeDeclare(TOPIC_EXCHAGE, BuiltinExchangeType.TOPIC);
        channel.addReturnListener(new ReturnListener() {
            @Override
            public void handleReturn(int replyCode, String replyText, String exchange, String routingKey, AMQP.BasicProperties properties, byte[] body) throws IOException {
                System.err.println("---------handle  return----------");
                System.err.println("replyCode: " + replyCode);
                System.err.println("replyText: " + replyText);
                System.err.println("exchange: " + exchange);
                System.err.println("routingKey: " + routingKey);
                System.err.println("properties: " + properties);
                System.err.println("body: " + new String(body));
            }
        });

        /*
            发送消息 && 参数解析
             参数1：交换机名称，如果没有指定则使用默认Default Exchage
             参数2：路由key,简单模式可以传递队列名称
             参数3：mandatory 属性
             参数4：消息其它属性
             参数5：消息内容
         */
        String message = "测试return listener" ;
        // basicPublish方法参数boolean mandatory默认是false，需要设置为true。
        //    当mandatory标志位设置为true时，如果exchange根据自身类型和消息routingKey无法找到一个合适的queue存储消息，
        //    那么broker会调用basic.return方法将消息返还给生产者;当mandatory设置为false时，出现上述情况broker会直接将消息丢弃;
        //    通俗的讲，mandatory标志告诉broker代理服务器至少将消息route到一个队列中，否则就将消息return给发送者;
        channel.basicPublish(TOPIC_EXCHAGE, "item.insert", true,null, message.getBytes());
        System.out.println("已发送消息：" + message);

    }
}
